import Cocoa

//var str = "Hello, playground"

//数组的初始化:
//1.字面量:如果使用字面量的方式初始化一个空数组,需要填写数组的类型
//var array = [1, 2, 3, 4, 5]
//print(array)
//如果使用字面量的方式初始化一个空数组,需要填写数组的类型
//使用字面量创建空数组的三种方式:
//let array2: Array<Int> = []
//var array3 = [Int]()  //Swift中使用()进行对象的初始化,默认为空数组
//array3 = [2, 0, 4, 8]  //如果是var修饰的变量,则可以在初始化后,对数组进行赋值
//array3 = [9, 8, 6]  //再次重新赋值
//var array4 = Array<Int>()
//print(array2)
//print(array3)
//print(array4)

//创建任意值"Z",重复5遍
//let fiveZs = Array(repeating: "Z", count: 5)
//let array = Array(repeating: 5, count: 3)
//print(fiveZs)
//print(array)

//将字符串拆分成字符添加到数组中
//let array2 = Array("hello")
//print(array2)


//let numbers = Array(1...9)
//print(numbers)

//将数组中的字典输出两个键和值的数组
//let person = ["zhangsan": 19, "lisi": 15, "wangwu": 18]
//print(person.keys, person.values)


//数组的遍历
//for i in Array(1...9) {
//    print(i)
//}

//使用forEach时无法使用continue或者break跳出整个循环,使用return也只能跳出当前循环
//如果写break获取continue会报错,显示break只能在循环或者switch中, continue只能允许使用在循环中
//let numbers = [Int](2...7 )
//numbers.forEach { (num) in
//    if num == 3 {
//        return  //return也只能跳出当前循环
//    }
//    print(num * 10)
//}
//输出结果: 20  40  50  60  70


//该方法可以循环输出元组类型，包含下标index及对应的item:enumerated
//let number = [Int](2...7)
//for (index, num) in number.enumerated() {   //enumerated:枚举,数,点
//    print("the index is \(index)")
//    print(num * 10)
//}
/**
 输出结果:
 the index is 0
 20
 the index is 1
 30
 the index is 2
 40
 the index is 3
 50
 the index is 4
 60
 the index is 5
 70
 */


//使用makeIterator遍历数组
//let numbers = [Int](2...7)
//var numIterator = numbers.makeIterator()   //Iterator: 迭代器
//while let num = numIterator.next() {
//    print(num)
//    print(num * 10)
//}

//使用indices指数来获取数组的索引区间   indices:指数,目录
//let numbers = [Int](2...7)
//print(numbers.indices)  //获取数组的索引区间
//for i in numbers.indices {
//    print(numbers[i])   //遍历数组
//}

//数组的查找
//let numbers: [Int] = Array(2...7)
////判断数组中是否包含5
//print(numbers.contains(5))
//print(numbers.contains(where: {$0 < 1}))   //$0:表示闭包中的第一个参数  结果为false

//let numbers = [1,2,5,4,3,6,8,7]
////从小到大的排列顺序
//var sortNumbers = numbers.sorted(by: { (a, b) -> Bool in
//    return a < b
//})
//print(sortNumbers)
//print("numbers -" + "\(sortNumbers)")

//使用闭包$0, $1 ，参数类型可以自动判断，并且in关键字也可以省略，也就是只用写函数体就可以了。
//let numbers = [1,2,5,4,3,6,8,7]
//var sortNumbers = numbers.sorted(by: {$0 < $1})
//print("numbers -" + "\(sortNumbers)")



//判断数组的元素都符合给定的条件
//var array = [10, 20, 45, 30, 98, 101, 30 ,4]
////判断数组中的元素是否都大于10     Satisfy:使满意, 符合(方程式)
//print(array.allSatisfy({$0 > 10}))  //false
////判断数组中的元素是否都大于等于4
//print(array.allSatisfy({$0 >= 4}))   //true


//都是可选项:获取数组中符合条件的某个对象(查找元素)
//var array = [10, 20, 45, 30, 98, 101, 30 ,4]
////输出数组中的第一个元素
//print(array.first)   //first这个属性是个可选项值
////输出数组中的最后一个元素
//print(array.last)
////输出数组中第一个大于30的元素
//print(array.first(where: {$0 > 30}) ?? 0)
////输出数组中最后一个大于100的元素
//print(array.last(where: {$0 > 100}))


//查找索引:获取数组中符合条件的某个索引, 0都是可选项值
//var array = [10, 20, 45, 30, 98, 101, 30 ,4]
////获取数组中第一个等于30的索引
//print(array.firstIndex(of: 30) ?? 0)   //结果:3,数组中第3个索引等于30,索引从0开始
//print(array.lastIndex(of: 30))   //结果: Optional(6),因为获取的结果是一个可选项,如果给定一个默认值的话就不会有警告了
//print(array.firstIndex(where: {$0 > 25}))
//print(array.lastIndex(where: {$0 > 25}))


//查找数组中的最大元素和最小元素,还是可选项
//var array = [10, 20, 45, 30, 98, 101, 30 ,4]
//print(array.min() ?? 0)
//print(array.max() ?? 100000)


//利用给定的方式比较元素并返回数组中的最小以及最大元素
//var array2 = [(23, "error23"), (45, "error45"), (66, "error66")]  //数组中包裹元组
//print(array2.min(by: { (a, b) -> Bool in   //输出最小数的元素(元组)
//    a.0 < b.0
//}) ?? 0)
//print(array2.max(by: { (a, b) -> Bool in
//    a.0 < b.0
//}) ?? 100)


//在末尾添加元素
//var numbers = [Int](2...7)
//numbers.append(100)
//print(numbers)
////在数组的末尾元素添加一个有顺序的值
//numbers.append(contentsOf: 101...103)  //sequence: 顺序，次序；连续事件（或动作、事物）
//print(numbers)


//在指定的末尾插入元素
//var numbers = [Int](2...7)
////在下标为1的数组中插入元素100
//numbers.insert(100, at: 1)
//print(numbers)
////在下标为0的数组中插入一个集合
//numbers.insert(contentsOf: -2...0, at: 0)
//print(numbers)




//移除指定下标的元素
//var numbers = [Int](2...7)
////删除下标为2的数组元素
//var num = numbers.remove(at: 2)
//print("num is \(num), numbers is \(numbers)")


//移除单个元素
//var numbers = [Int](2...7)
////移除数组中第一个元素
//var firstNum = numbers.removeFirst()
//print("firstNum is \(firstNum), numbers is \(numbers)")
////删除数组中最后一个元素
//var lastNum = numbers.removeLast()
//print("lastNum is \(lastNum), numbers is \(numbers)")


//移除多个元素,参与移除的变量打印为空
//var numbers = [Int](2...7)
////移除数组中最前面的两个元素
//var firstNum = numbers.removeFirst(2)
//print("firstNum is \(firstNum), numbers is \(numbers)")
//
//var lastNum = numbers.removeLast(2)
//print("lastNum is \(lastNum), numbers is \(numbers)")

//var numbers = [Int](2...7)
//var popNum = numbers.popLast()   //popNum是一个可选项
//print("popNum is \(String(describing: popNum)), numbers is \(numbers)")


//var numbers = [Int](2...7)
////删除下标为1和2的元素,此时这个变量为空
//var rangeNum = numbers.removeSubrange(1...2)
//print("rangeNum is \(rangeNum), numbers is \(numbers)")


//var numbers = [Int](2...7)
//numbers.removeAll(keepingCapacity: true) //Capacity:容积,容纳能力
//print(numbers)
//print(numbers.capacity)

//数组切片arraySlice
//获取数组切片
//var array = [5, 2, 10, 1, 0, 100, 46, 99]
////drop:投.丢,剔除,除名,放弃,停止
//print(array.dropFirst())  //对原数组不产生影响
//print(array.dropLast())
////剔除前面两个元素
//print(array.dropFirst(2))
////剔除后面两个元素
//print(array.dropLast(2))
////移除原数组符合条件的指定元素返回一个arraySlice数组切片
//print(array.drop(while: {$0 < 10})) //当while的条件不成立时,输出后面的元素  输出的是条件不成立的值


//通过prefix得到arraySlice
//var array = [5, 2, 10, 1, 0, 100, 46, 99]
////array.prefix(3) //得到前面3位数组元素
//print(array.prefix(3))  //对原数组没有影响
//print(array)
//print(array.prefix(upTo: 5)) //得不到第五位
//print(array.prefix(through: 5)) //可以取到第五位
//print(array.prefix(while: {$0 < 100}))  //输出符合条件的数组元素的数组


//通过suffix得到arraySlice
//var array = [5, 2, 10, 1, 0, 100, 46, 99]
//array.suffix(4)  //获取到后面四位
//array.suffix(from: 3) //从第三位开始,可以取到第三位
//
////通过range得到arraySlice
//array[3...5]   //获取下标为3到5的元素的数组
//array[...] //获取整个数组的元素
//array[...6]
//let slice = array[3...]



//将arraySlice转化为array:使用初始化器来转化
//var array2 = Array(slice)
//print(array2)

//ArraySlice和原Array都是独立存在的,对他们进行插入和删除操作都不会互相影响对方
//var array = [10, 46, 99]
//var slice = array.dropFirst()
//print(array)
//print(slice)
//array.append(100)
//slice.insert(77, at: 1)
//print(array)
//print(slice)


//数组的重排操作
//var array = [Int](1...8)
//array.shuffle()  //将数组元素随机排放
//print(array)
//
//let array2 = array.shuffled()   //shuffled:拖曳, 搅乱
//print(array) //原数组不变
//print(array2)

//数组的逆序
//var array = [Int](1...8)
//array.reverse()  //reverse:颠倒,反转
//let array2 = array.reversed()
//print(array)
//print(array2)
//for i in array2 {
//    print(i)
//}


//数组的分组 partition:划开,分开,分割
//var array = [10, 20, 45, 30, 98, 101, 30, 4]
//let index = array.partition(by: {$0 > 30})   //partition:分隔,分裂,隔开
//print(array)
//print(index)
//let partition1 = array[..<index]
//let partition2 = array[index...]
//print(partition1)
//print(partition2)


//数组的排序
//var array = [10, 20, 45, 30, 98, 101, 30, 4]
//array.sort()
//let array2 = array.sorted()
//print(array)
//print(array2)

//交换数组两个元素 swap:交换,调换,代替
//var array = [10, 20, 45, 30, 98, 101, 30, 4]
//array.swapAt(array.startIndex, array.endIndex - 1)  //将第一个元素和最后一个元素调换了位置
//print(array)


//数组元素的拼接,最后成为一个字符串(数组转字符串)
//字符串数组的拼接   sequence:  序列；顺序；续发事件
//var array = ["1","2","3","4","5","6","7"]
//print(array.joined())
////如果你想要的结果字符串依然包含分割符可以使用如下方法分割
//print(array.joined(separator: ","))


//元素为sequence的数组拼接
let ranges = [0..<3, 8..<10, 15..<17]
for range in ranges {
    print(range)
}

for i in ranges.joined() {
    print(i)
}

let nestedNumbers = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let joined = nestedNumbers.joined(separator: [-1, -2])
print(joined)
print(Array(joined))  //将多个数组拼接数组后变成一个数组
